<template>
  <div>
    <el-form>
      <el-form-item label="SPU名称">
        <el-input placeholder="请输入SPU名称" v-model="spuParams.saleAttrName"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select placeholder="请选择" filterable v-model="spuParams.tmId">
          <el-option :value="trademark.id" :label="trademark.tmName" v-for="(trademark,index) in allTradeMarkArr"
            :key="trademark.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input type="textarea" label="请输入SPU描述" v-model="spuParams.description"></el-input>

      </el-form-item>

      <el-form-item label="SPU图片">
        <el-upload v-model:file-list="imgListArr" action="/api/admin/product/fileUpload" list-type="picture-card"
          :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleSuccess">
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select :placeholder="unSelectSaleAttr.lengt>0?`还有${unSelectSaleAttr.length}未选择` : '没有可选的啦'" filterable
          v-model="unSaleAttrIdAndName">
          <el-option :value="`${sale.id}:${sale.name}`" :label="sale.name" v-for="(sale,index) in unSelectSaleAttr"
            :key="sale.id">
          </el-option>
        </el-select>
        <el-button type="primary" size="default" :icon="Plus" :disabled="!unSaleAttrIdAndName" @click="addSaleAttr"
          style="margin-left:10px">添加销售属性</el-button>
        <el-table border stripe style="margin:10px 0px" :data="spuHasSaleAttrArr">
          <el-table-column type="index" label="序号" align="center" width="80px">
          </el-table-column>
          <el-table-column label="属性名" width="150px" prop="saleAttrName">
          </el-table-column>
          <el-table-column label="属性值名称列表">
            <template #="{row,$index}">
              <el-tag style="margin:2px 5px" v-for="(saleValue,index) in row.spuSaleAttrValueList" :key="saleValue.id"
                class="mx-1" closable @close="row.spuSaleAttrValueList.splice(index,1)" :type="success">
                {{saleValue.saleAttrValueName}}</el-tag>
              <!-- button与input的切换:编辑模式与查看模式切换 -->
              <el-input v-if="row.flag" placeholder="请你输入属性值" size="small" style="width: 100px" @blur="toLook(row)"
                v-model="row.inputValue"></el-input>
              <el-button v-else type="primary" size="small" :icon="Plus" @click="toEdit(row)"></el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120">
            <template #="{ row, $index }">
              <el-button type="danger" size="small" :icon="Delete" @click="spuHasSaleAttrArr.splice($index, 1)">
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-button type="primary" size="default" @click="save">保存</el-button>
        <el-button size="default" @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>


  </div>
</template>

<script setup lang="ts">
//照片墙
import { ref,computed } from 'vue'
import { Plus,Delete} from '@element-plus/icons-vue'

import type { UploadProps, UploadUserFile } from 'element-plus'
import  { ElMessage } from 'element-plus'
//引入请求函数
import { reqAllaTradeMark, reqAllSaleAttr, reqImgList, reqSpuHasSaleAttr, reqAddOrUpdateSpu } from '../../../api/product/spu/spu'
//存储相应服务器返回的数据---四个数组

//已有SPU下的全部品牌数据
let allTradeMarkArr = ref([]);
//获取已有SPU下照片墙的数据
let imgListArr = ref([]);
//获取已有SPU，拥有销售属性
let spuHasSaleAttrArr = ref([]);
//获取全部销售属性[不管任何SPU销售属性最多三个]
let allSaleAttrArr = ref([]);
//储存数据
let spuParams = ref({});
//收集SPU还没选择销售属性ID和名字
let unSaleAttrIdAndName = ref('');
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

//删除图片回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  //第一个参数:uploadFile,删除掉的图片信息  第二个参数:uploadFiles删除完毕剩下图片的信息
  imgListArr.value = uploadFiles;
};

//图片上传成功的回调
const handleSuccess = (response, uploadFile, uploadFiles) => {
  //前两个参数:图片上传成功的信息
  //最后的参数:图片上传成功以后，照片墙全部图片数据
  imgListArr.value = uploadFiles;
};

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
};

//提供一个方法:将来父组件可以借用的方法
const initHasSpuData = async (spu) => {
  console.log(spu);
  //获取数据
  spuParams.value = spu;

  //在父组件点击修改SPU按钮的时候，触发子组件当前方法，向服务器发四个请求
  //获取全部品牌数据
  let ps1 = reqAllaTradeMark();
  //获取已有SPU照片墙的数据
  let ps2 = reqImgList(spu.id);
  //获取当前SPU已有销售属性
  let ps3 = reqSpuHasSaleAttr(spu.id);
  //获取全部销售属性
  let ps4 = reqAllSaleAttr();
  //获取全部服务器返回数据
  let result = await Promise.all([ps1, ps2, ps3, ps4]);
  //存储全部品牌
  allTradeMarkArr.value = result[0];
  //存储照片墙的数据
  imgListArr.value = result[1];
  //存储已有销售属性
  spuHasSaleAttrArr.value = result[2];
  //获取全部销售属性
  allSaleAttrArr.value = result[3];
  //储存照片墙的数据
  //由于服务器返回的数据不符合照片墙需求，需要更换
  imgListArr.value = result[1].map((item)=>{
    return {
      name:item.imgName,
      url:item.imgUrl,
    };
  });
  //储存已有销售属性
  spuHasSaleAttrArr.value = result[2];
  //获取全部销售属性
  allSaleAttrArr.value = result[3];
};
//计算出当前SPU，还没有选择销售属性
let unSelectSaleAttr = computed(()=>{
  //过滤出来需要的
let result = allSaleAttrArr.value.filter((item)=>{
  //回调函数返回布尔值，真代表过滤，false代表新的数组不要
  return spuHasSaleAttrArr.value.every((item1)=>{
    return item.name != item1.saleAttrName;
  });
});
return result;
})
//点击添加销售属性按钮回调
const addSaleAttr = () => {
  //整理参数
  //新增的销售属性ID与名字
  const [baseSaleAttrId, saleAttrName] = unSaleAttrIdAndName.value.split(":");
  //服务器需要销售属性对象
  let newSaleAttr = { baseSaleAttrId, saleAttrName, spuSaleAttrValueList: [] };
  //向SPU已有的数组里面追加新增销售是属性
  spuHasSaleAttrArr.value.push(newSaleAttr);
  //清空下拉框的数据
  unSaleAttrIdAndName.value = "";
};

//点击按钮变为编辑模式
const toEdit = (row) => {
  //动态追加flag属性
  //Proxy对象:动态追加的属性也是相应式的
  row.flag = true;
  //追加一个属性：收集销售属性值---有一个起始数值 空串
  row.inputValue = "";
};

//表单元素input失却焦点的事件回调
//row:即为当前销售属性
const toLook = (row) => {
  //属性值非法的情况判断
  console.log(row.inputValue);
  //收集属性值为空
  if (row.inputValue.trim() == "") {
    ElMessage({
      type: "error",
      message: "属性值不能为空",
    });
    return;
  }

  //收集属性值不能与前面已有属性值重复
  let repeat = row.spuSaleAttrValueList.find((item) => {
    //item:已有的销售属性值对象      row.inputValue 新增属性值名称
    return item.saleAttrValueName === row.inputValue;
  });
  //如果出现重复属性值后面的代码不能执行
  if (repeat) {
    ElMessage({
      type: "error",
      message: "属性值名称不能重复",
    });
    //清空最新收集同名属性值
    row.inputValue = "";
    //如果出现同名的属性值显示button
    row.flag = false;
    return;
  }

  //显示button设置
  row.flag = false;
  //新增属性值
  let newSaleattrVal = {
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: row.inputValue,
  };
  //追加到当前销售属性值的数组里面
  row.spuSaleAttrValueList.push(newSaleattrVal);
  //清空收集属性值数据
  row.inputValue = "";
};

//按钮保存的事件回调
const save = async () => {
  //整理参数
  //整理照片墙的数据
  spuParams.value.spuImageList = imgListArr.value.map((item) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    };
  });
  //整理销售属性的参数
  spuParams.value.spuSaleAttrList = spuHasSaleAttrArr.value;
  //发请求:修改|添加
  try {
    await reqAddOrUpdateSpu(spuParams.value);
    ElMessage({
      type: "success",
      message: spuParams.value.id ? "修改成功" : "添加成功",
    });
    //触发自定义事件
    emit("changeScene", {
      scenes: 0,
      flag: spuParams.value.id ? "update" : "add",
    });
    //清空数据
    resetData();
  } catch (error) {
    ElMessage({
      type: "error",
      message: spuParams.value.id ? "修改失败" : "添加失败",
    });
  }

  //触发自定义事件通知父组件切换场景0
};

//取消
const cancel = () => {
  emit("changeScene", {
    scenes: 0,
    flag: spuParams.value.id ? "update" : "add",
  });
  resetData();
};

//清空数据
const resetData = () => {
  spuParams.value = {};
  imgListArr.value = [];
  spuHasSaleAttrArr.value = [];
};

//点击添加SPU的时候，当前子组件发请求(两个:获取全部品牌|全部销售属性)
const initAddSpu = async (c3Id: string | number) => {
  //添加SPU追加三级分类ID
  spuParams.value.category3Id = c3Id;
  //获取全部品牌数据
  let ps1 = reqAllaTradeMark();
  //获取全部销售属性
  let ps2 = reqAllSaleAttr();
  let result = await Promise.all([ps1, ps2]);
  //存储全部品牌
  allTradeMarkArr.value = result[0];
  //获取全部销售属性
  allSaleAttrArr.value = result[1];
};

//触发自定义事件
let emit = defineEmits(["changeScene"]);
//对外暴露方法
defineExpose({
  initHasSpuData,
  initAddSpu,
});
</script>

<style scoped>

</style>